package com.reguang.aspect;

import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.alibaba.fastjson.JSONObject;
import com.reguang.annotation.ParamsNotNull;
import com.reguang.enums.ResultCode;
import com.reguang.utils.RequestContextHolderUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * 
 * <p>Title: ParamsInterceptor</p>
 * <p>Description: 参数校验处理类</p>
 * @author weibiao
 * @date 2019年12月27日
 */
@Slf4j
public class ParamsInterceptor extends HandlerInterceptorAdapter {

	/**
	 * 重写父类方法
	 */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		if (!(handler instanceof HandlerMethod)) {
			log.warn("暂时不支持的处理类型");
			return true;
		}
		// 拿到该方法上加了注解的参数名称
		List<String> params = getParamsName((HandlerMethod) handler);
		for (String param : params) {
			String parameterValue = request.getParameter(param);
			if (StringUtils.isEmpty(parameterValue)) {
				log.error("【参数名称】 result : {},【参数值】 result : {}", param, parameterValue);// 记录日志
				JSONObject jsonObject = new JSONObject();
				jsonObject.put("code", ResultCode.PARAM_IS_BLANK.code());
				jsonObject.put("message", param + " 不能为空");
				jsonObject.put("path", RequestContextHolderUtil.getRequest().getRequestURI());
				jsonObject.put("timestamp", new Date());
				response.setHeader("Content-type", "application/json;charset=UTF-8");
				response.getWriter().write(jsonObject.toJSONString());
				return false;
			}

		}
		// 如果拿到的对象为空,说明没有此注解,直接放行
		return true;
	}

	/**
	 * 
	 * <p>Title: getParamsName</p>
	 * <p>Description: 获取参数名称</p>
	 * @remark 此处获取参数名称需jdk1.8以上，并且打开IDE的store information about method parameters否则需反编译自己获取参数名称
	 * @param handlerMethod
	 * @return
	 */
	private List<String> getParamsName(HandlerMethod handlerMethod) {
		Parameter[] parameters = handlerMethod.getMethod().getParameters();
		List<String> list = new ArrayList<String>();
		for (Parameter parameter : parameters) {
			if (parameter.isAnnotationPresent(ParamsNotNull.class)) {
				list.add(parameter.getName());
			}
		}
		return list;
	}
}
